#ifndef Partie_h
#define Partie_h

#include <vector>
#include "De.h"

class Joueur;
class Territoire;
class De;

/**
 * Classe enumerant les phases d'une partie
 */
class Step
{
  public:

   enum StepEnum { CHOOSE_ARMY, CHOOSE_ENEMY, LANCERDE, ATTACK, ENDSTEP };
  Step(enum StepEnum _step=CHOOSE_ARMY) : step_enum(_step) { }
   void set(enum StepEnum _step) { step_enum=_step; }
   void toggle();

   operator const char *()
   {
      switch(step_enum)
      {
         case CHOOSE_ARMY: return "Vous devez choisir le territoire avec lequel vous souhaitez attaquer.";
         case CHOOSE_ENEMY: return "Vous devez choisir le terrtoire ennemie que vous souhaitez attaquer.";
         case LANCERDE: return "Vous lancez les des.";
         case ATTACK: return "ATTACK";
         case ENDSTEP: return "ENDSTEP";
         default: return "This step isn't implemented !";
      }
   }
   bool operator==(const Step _step) const 
   {
      return step_enum==_step.step_enum;
   }
   operator enum StepEnum()
   {
      return step_enum;
   }

  public:
   enum StepEnum step_enum;

};

/**
 * Classe Partie
 */
class Partie
{

  public:
   Partie();
   ~Partie();
   void initFirstPlayer();
   void initPlayers();
   void distribuerTerritoires();
   void nextStep();
   void doStep(Territoire* _territoire=NULL);

   std::vector< Joueur * > * getJoueurs() { return &joueurs; }
   Joueur * getCurrentPlayer() { return *currentPlayer; }
   Joueur* getJoueur(int _index) { return joueurs[_index]; }
   Territoire* getTerritoireArmy() { return territoireArmy; }
   Territoire* getTerritoireEnemy() { return territoireEnemy; }   
   Step::StepEnum getStep() { return *step; }
   //static int animDe(void * _partie);

   int getResultArmy() { return result_territoireArmy;}
   void setResultArmy(int _army) { result_territoireArmy = _army;}
   int getResultEnemy() { return result_territoireEnemy ;}
   void setResultEnemy(int _enemy) { result_territoireEnemy = _enemy;}
  
   int getBestScoreAttak();
   int getBestScoreDef();

   void animDeStart() { finAnimDe = false; }
   void animDeEnd() { finAnimDe = true; }
   bool isEndOfAnimDe() { return finAnimDe; }
   void resetAllDeState();
   bool allDeStopped();

   De *getDeAttak() { return deAttak; }
   De *getDeDef(){ return deDef; }
   static const int NBDE = 3;

  protected:
   Joueur * nextPlayer();
   bool selectTerritoireArmy(Territoire* _territoire);
   bool selectTerritoireEnemy(Territoire* _territoire);
   void attack();

  protected:
   std::vector< Joueur * > joueurs; 
   std::vector< Joueur * >::const_iterator currentPlayer;
   Step* step;
  

   Territoire* territoireArmy;
   Territoire* territoireEnemy;

   Territoire* territoireWinner;
   Territoire* territoireLooser;

   De deAttak[Partie::NBDE];
   De deDef[Partie::NBDE];

   int result_territoireArmy;
   int result_territoireEnemy;

   bool finAnimDe;

};

#endif
